home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 60 / IOPROG_60.ISO / soft / c++ / gsl-1.1.1-setup.exe / {app} / src / fft / c_init.c < prev    next >
Encoding:
Text File  |  2001-08-22  |  4.7 KB  |  195 lines

  1. /* fft/c_init.c
  2.  * 
  3.  * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough
  4.  * 
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or (at
  8.  * your option) any later version.
  9.  * 
  10.  * This program is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * General Public License for more details.
  14.  * 
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. TYPE(gsl_fft_complex_wavetable) * 
  21. FUNCTION(gsl_fft_complex_wavetable,alloc) (size_t n)
  22. {
  23.   int status ;
  24.   size_t i;
  25.   size_t n_factors;
  26.   size_t t, product, product_1, q;
  27.   double d_theta;
  28.  
  29.   TYPE(gsl_fft_complex_wavetable) * wavetable ;
  30.  
  31.   if (n == 0)
  32.     {
  33.       GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0);
  34.     }
  35.  
  36.   wavetable = (TYPE(gsl_fft_complex_wavetable) *) 
  37.     malloc(sizeof(TYPE(gsl_fft_complex_wavetable)));
  38.  
  39.   if (wavetable == NULL)
  40.     {
  41.       GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0);
  42.     }
  43.  
  44.   wavetable->trig = (TYPE(gsl_complex) *) malloc (n * sizeof (TYPE(gsl_complex)));
  45.  
  46.   if (wavetable->trig == NULL)
  47.     {
  48.       free(wavetable) ; /* error in constructor, prevent memory leak */
  49.  
  50.       GSL_ERROR_VAL ("failed to allocate trigonometric lookup table", 
  51.             GSL_ENOMEM, 0);
  52.     }
  53.  
  54.   wavetable->n = n ;
  55.  
  56.   status = fft_complex_factorize (n, &n_factors, wavetable->factor);
  57.  
  58.   if (status)
  59.     {
  60.       /* exception in constructor, avoid memory leak */
  61.  
  62.       free (wavetable->trig);
  63.       free (wavetable);        
  64.  
  65.       GSL_ERROR_VAL ("factorization failed", GSL_EFACTOR, 0);
  66.     };
  67.  
  68.   wavetable->nf = n_factors;
  69.  
  70.   d_theta = -2.0 * M_PI / ((double) n);
  71.  
  72.   t = 0;
  73.   product = 1;
  74.   for (i = 0; i < n_factors; i++)
  75.     {
  76.       size_t j;
  77.       const size_t factor = wavetable->factor[i];
  78.       wavetable->twiddle[i] = wavetable->trig + t;
  79.       product_1 = product;    /* product_1 = p_(i-1) */
  80.       product *= factor;
  81.       q = n / product;
  82.  
  83.       for (j = 1; j < factor; j++)
  84.     {
  85.       size_t k;
  86.       size_t m = 0;
  87.       for (k = 1; k <= q; k++)
  88.         {
  89.           double theta;
  90.           m = m + j * product_1;
  91.           m = m % n;
  92.           theta = d_theta * m;    /*  d_theta*j*k*p_(i-1) */
  93.           GSL_REAL(wavetable->trig[t]) = cos (theta);
  94.           GSL_IMAG(wavetable->trig[t]) = sin (theta);
  95.  
  96.           t++;
  97.         }
  98.     }
  99.     }
  100.  
  101.   if (t > n)
  102.     {
  103.       /* exception in constructor, avoid memory leak */
  104.  
  105.       free (wavetable->trig);
  106.       free (wavetable);
  107.  
  108.       GSL_ERROR_VAL ("overflowed trigonometric lookup table", 
  109.                         GSL_ESANITY, 0);
  110.     }
  111.  
  112.   return wavetable;
  113. }
  114.  
  115.  
  116. TYPE(gsl_fft_complex_workspace) * 
  117. FUNCTION(gsl_fft_complex_workspace,alloc) (size_t n)
  118. {
  119.   TYPE(gsl_fft_complex_workspace) * workspace ;
  120.  
  121.   if (n == 0)
  122.     {
  123.       GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0);
  124.     }
  125.  
  126.   workspace = (TYPE(gsl_fft_complex_workspace) *) 
  127.     malloc(sizeof(TYPE(gsl_fft_complex_workspace)));
  128.  
  129.   if (workspace == NULL)
  130.     {
  131.       GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0);
  132.     }
  133.  
  134.   workspace->n = n ;
  135.  
  136.   workspace->scratch = (BASE *) malloc (2 * n * sizeof (BASE));
  137.  
  138.   if (workspace->scratch == NULL)
  139.     {
  140.       free(workspace) ; /* error in constructor, prevent memory leak */
  141.  
  142.       GSL_ERROR_VAL ("failed to allocate scratch space", GSL_ENOMEM, 0);
  143.     }
  144.   
  145.   return workspace;
  146. }
  147.  
  148.  
  149. void
  150. FUNCTION(gsl_fft_complex_wavetable,free) (TYPE(gsl_fft_complex_wavetable) * wavetable)
  151. {
  152.  
  153.   /* release trigonometric lookup tables */
  154.  
  155.   free (wavetable->trig);
  156.   wavetable->trig = NULL;
  157.  
  158.   free (wavetable) ;
  159. }
  160.  
  161. void
  162. FUNCTION(gsl_fft_complex_workspace,free) (TYPE(gsl_fft_complex_workspace) * workspace)
  163. {
  164.   /* release scratch space */
  165.  
  166.   free (workspace->scratch);
  167.   workspace->scratch = NULL;
  168.   free (workspace) ;
  169. }
  170.  
  171.  
  172. int
  173. FUNCTION(gsl_fft_complex,memcpy) (TYPE(gsl_fft_complex_wavetable) * dest,
  174.                                   TYPE(gsl_fft_complex_wavetable) * src)
  175. {
  176.   int i, n, nf ;
  177.  
  178.   if (dest->n != src->n) 
  179.     {
  180.       GSL_ERROR ("length of src and dest do not match", GSL_EINVAL);
  181.     } 
  182.   
  183.   n = dest->n ;
  184.   nf = dest->nf ;
  185.  
  186.   memcpy(dest->trig, src->trig, n * sizeof (double)) ;
  187.   
  188.   for (i = 0 ; i < nf ; i++)
  189.     {
  190.       dest->twiddle[i] = dest->trig + (src->twiddle[i] - src->trig) ;
  191.     }
  192.  
  193.   return 0 ;
  194. }
  195.